home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
051-075
/
disk_070
/
blackbook
/
blkbook.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
21KB
|
763 lines
/*
------------------------------------
*** Little Black Book © 1987 Lcc ***
------------------------------------
This program is presented in the spirit of keeping shareware alive.
You may freely copy and distribute, for non-commercial purposes, both
Little Black Book and the limited file handler library (bfile.lib) provided
that this documentation accompanies the programs and that no charge is made
for copying and distribution.
If you find these programs useful please send your contribution to the
address below. If you desire the full-blown bfile library on disk complete
with source code (bfile is written in 'C' and is not Amiga specific) -
Please send the nominal fee of $30¹ to:
Craig Nelson
Log Cabin Computer
921 Arcola Ct PP
Granbury, TX 76048
¹ A bona fide job offer may be substituted for cash as this programmer is
currently unemployed (817) 573-7304.
Notes, caveats and stuff
--------------------------
* Because of special keyboard/mouse handling, runs only under WorkBench
release 1.2 (this does not apply to bfile.lib)
* Set up for 80 column because that's my preference
* If the display flashes it's either your imagination or the beginning or
end of file has been reached
* For the most part, either the keyboard or the mouse may be used
interchangeably - you'll get the idea just by playing around
<Right Mouse> move pointer to the bottom of window
<RETURN> when the pointer is at the bottom of window enters
edit mode
<CTRL><RETURN> exits edit mode
<Right AMIGA><Q> restores a field
<Right AMIGA><X> clears a field
<Right Cursor> next record
<Left Cursor> previous record
F1 - 'FND' finds the first occurence > or = to entry typed
(the record key is upper case so 'johnson' = 'JOHNSON')
F2 - 'SAV' saves changes made to an existing record
F3 - 'ADD' adds a new record
F4 - 'DEL' deletes a record
- - -
*/
#include <intuition/intuition.h>
#include <devices/input.h>
#define BLUP 0
#define WHTP 1
#define BLKP 2
#define YLWP 3
#define MESSAGE (1 << wdw->UserPort->mp_SigBit)
#define IGNORE_MSG ((qual & 0x0200) || (code & 0x80)) /* Key up, repeat */
#define ABORT_MSG (qual & 0x2008) /* CTRL, RMB */
#define FND_KEY 0x50 /* F1 */
#define SAV_KEY 0x51 /* F2 */
#define ADD_KEY 0x52 /* F3 */
#define DEL_KEY 0x53 /* F4 */
#define EDT_KEY 0x44 /* Return */
#define PRV_KEY 0x4F /* Left arrow */
#define NXT_KEY 0x4E /* Right arrow */
#define NAM_GAD 1
#define ADR_GAD 2
#define CIT_GAD 3
#define STA_GAD 4
#define ZIP_GAD 5
#define PHN_GAD 6
#define NOT_GAD 7
#define FND_GAD 8
#define SAV_GAD 9
#define ADD_GAD 10
#define DEL_GAD 11
#define PRV_GAD 12
#define NXT_GAD 13
#define NEG_GAD 14
#define POS_GAD 15
#define STR_GAD 7 /* End of string gadgets */
#define WDW_GAD 13 /* End of normal gadgets */
/*------------------------ Required by bfile.lib -------------------------*/
extern int BFILE_OK;
typedef char BFILE[100];
/*----------------------- Database file definition -----------------------*/
#define DUP 1 /* Duplicate records OK */
typedef char BKEY[26]; /* Record key */
struct DataRec {
char Name[26],
Addr[26],
City[15],
State[3],
Zip[6],
Phone[15],
Note[81];
} BookRec, SaveRec;
BFILE BookDataFile;
BFILE BookIndexFile;
BKEY BookKey;
int BookRecNum;
/*---------------------- Special external functions ----------------------*/
extern struct MsgPort *CreatePort();
extern struct IOStdReq *CreateStdIO();
extern struct TextFont *OpenFont();
/*----------------------------- Global data ------------------------------*/
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Window *wdw;
struct IntuiMessage *msg;
struct RastPort *rp;
struct MsgPort *dev;
struct IOStdReq *req;
struct TextFont *font;
ULONG class;
USHORT code;
USHORT qual;
APTR iadr;
USHORT gid;
short find_flag;
char Undo[81];
char Note[26];
char used[8];
char
wdwttl[] = { " Little Black Book © 1987 Lcc " },
scrttl[] = { "Little Black Book © 1987 Lcc (817) 573-7304 WB 1.2 80 col" };
struct TextAttr
attr = { "topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT };
struct InputEvent
epos = { NULL, IECLASS_POINTERPOS, 0, IECODE_NOBUTTON, 0,0,0,0 },
ebut = { NULL, IECLASS_POINTERPOS, 0, IECODE_LBUTTON, 0,0,0,0 };
USHORT prv_pix[] = { 0xFE3F,0xF87F,0xC0FF,0x0000,0xC0FF,0xF87F,0xFE3F },
nxt_pix[] = { 0xFC7F,0xFE1F,0xFF03,0x0000,0xFF03,0xFE1F,0xFC7F };
struct Image
prv_img = { 4,0, 16,7,1, (USHORT *) &prv_pix, 0x2,0x0, NULL },
nxt_img = { 4,0, 16,7,1, (USHORT *) &nxt_pix, 0x2,0x0, NULL };
SHORT c03_pts[] = { -3,-1, 28,-1, 28,10, -3,10, -3,-1 },
c06_pts[] = { -3,-1, 52,-1, 52,10, -3,10, -3,-1 },
c15_pts[] = { -3,-1, 124,-1, 124,10, -3,10, -3,-1 },
c26_pts[] = { -3,-1, 212,-1, 212,10, -3,10, -3,-1 },
sel_pts[] = { -3,-1, 52,-1, 52, 9, -3, 9, -3,-1 };
struct Border
c03_brdr = { -1,-1, BLUP,BLKP,JAM1, 5,(SHORT *) &c03_pts, NULL },
c06_brdr = { -1,-1, BLUP,BLKP,JAM1, 5,(SHORT *) &c06_pts, NULL },
c15_brdr = { -1,-1, BLUP,BLKP,JAM1, 5,(SHORT *) &c15_pts, NULL },
c26_brdr = { -1,-1, BLUP,BLKP,JAM1, 5,(SHORT *) &c26_pts, NULL },
sel_brdr = { -1,-1, YLWP,BLKP,JAM1, 5,(SHORT *) &sel_pts, NULL },
neg_brdr = { -1,-1, BLKP,BLKP,JAM1, 5,(SHORT *) &c03_pts, NULL };
struct StringInfo
nam_info = { BookRec.Name , Undo, 0,26,0,0,0,0,0,0, NULL,0,NULL },
adr_info = { BookRec.Addr , Undo, 0,26,0,0,0,0,0,0, NULL,0,NULL },
cit_info = { BookRec.City , Undo, 0,15,0,0,0,0,0,0, NULL,0,NULL },
sta_info = { BookRec.State, Undo, 0, 3,0,0,0,0,0,0, NULL,0,NULL },
zip_info = { BookRec.Zip , Undo, 0, 6,0,0,0,0,0,0, NULL,0,NULL },
phn_info = { BookRec.Phone, Undo, 0,15,0,0,0,0,0,0, NULL,0,NULL },
not_info = { BookRec.Note , Undo, 0,81,0,0,0,0,0,0, NULL,0,NULL };
struct IntuiText
nam_text = { BLUP,BLKP,JAM1, -44, 0,&attr, "Name" , NULL },
adr_text = { BLUP,BLKP,JAM1, -44, 0,&attr, "Addr" , NULL },
cit_text = { BLUP,BLKP,JAM1, -44, 0,&attr, "City" , NULL },
sta_text = { BLUP,BLKP,JAM1, -52, 0,&attr, "State" , NULL },
zip_text = { BLUP,BLKP,JAM1, -44, 0,&attr, "Zip" , NULL },
phn_text = { BLUP,BLKP,JAM1, -28, 0,&attr, "Ph" , NULL },
not_text = { BLUP,BLKP,JAM1, -44, 0,&attr, "Note" , NULL },
fnd_text = { BLUP,BLKP,JAM1, 0, 0,&attr, "F1=FND" , NULL },
sav_text = { BLUP,BLKP,JAM1, 0, 0,&attr, "F2=SAV" , NULL },
add_text = { BLUP,BLKP,JAM1, 0, 0,&attr, "F3=ADD" , NULL },
del_text = { BLUP,BLKP,JAM1, 0, 0,&attr, "F4=DEL" , NULL },
usd_text = { BLUP,BLKP,JAM2, 0, 0,&attr, used , NULL },
neg_text = { BLKP,BLKP,JAM1, 4, 0,&attr, "No" , NULL },
pos_text = { BLKP,BLKP,JAM1, 0, 0,&attr, "Yes" , NULL },
avf_text = { BLKP,BLKP,JAM1, 48, 3,&attr, "Add Duplicate?" , NULL },
dvf_text = { BLKP,BLKP,JAM1, 48, 3,&attr, "Delete Record?" , NULL },
svf_text = { BLKP,BLKP,JAM1, 48, 3,&attr, "Changed - Save?", NULL },
not_disp = { WHTP,BLUP,JAM2, 56,71,&attr, Note , NULL },
phn_disp = { WHTP,BLUP,JAM2, 144,57,&attr, BookRec.Phone , ¬_disp },
zip_disp = { WHTP,BLUP,JAM2, 56,57,&attr, BookRec.Zip , &phn_disp },
sta_disp = { WHTP,BLUP,JAM2, 240,43,&attr, BookRec.State , &zip_disp },
cit_disp = { WHTP,BLUP,JAM2, 56,43,&attr, BookRec.City , &sta_disp },
adr_disp = { WHTP,BLUP,JAM2, 56,29,&attr, BookRec.Addr , &cit_disp },
nam_disp = { WHTP,BLUP,JAM2, 56,15,&attr, BookRec.Name , &adr_disp };
struct Gadget
nam_gdgt = { NULL, 56,15,208,8, GADGHCOMP, RELVERIFY, STRGADGET,
(APTR) &c26_brdr, NULL, &nam_text, 0, (APTR) &nam_info,
NAM_GAD, NULL },
adr_gdgt = { NULL, 56,29,208,8, GADGHCOMP, RELVERIFY, STRGADGET,
(APTR) &c26_brdr, NULL, &adr_text, 0, (APTR) &adr_info,
ADR_GAD, NULL },
cit_gdgt = { NULL, 56,43,120,8, GADGHCOMP, RELVERIFY, STRGADGET,
(APTR) &c15_brdr, NULL, &cit_text, 0, (APTR) &cit_info,
CIT_GAD, NULL },
sta_gdgt = { NULL, 240,43,24,8, GADGHCOMP, RELVERIFY, STRGADGET,
(APTR) &c03_brdr, NULL, &sta_text, 0, (APTR) &sta_info,
STA_GAD, NULL },
zip_gdgt = { NULL, 56,57,48,8, GADGHCOMP, RELVERIFY, STRGADGET,
(APTR) &c06_brdr, NULL, &zip_text, 0, (APTR) &zip_info,
ZIP_GAD, NULL },
phn_gdgt = { NULL,144,57,120,8, GADGHCOMP, RELVERIFY, STRGADGET,
(APTR) &c15_brdr, NULL, &phn_text, 0, (APTR) &phn_info,
PHN_GAD, NULL },
not_gdgt = { NULL, 56,71,208,8, GADGHCOMP, RELVERIFY, STRGADGET,
(APTR) &c26_brdr, NULL, ¬_text, 0, (APTR) ¬_info,
NOT_GAD, NULL },
fnd_gdgt = { NULL, 15,87,48,7, GADGHCOMP, RELVERIFY, BOOLGADGET,
(APTR) &sel_brdr, NULL, &fnd_text, 0, (APTR) NULL,
FND_GAD, NULL },
sav_gdgt = { NULL, 76,87,48,7, GADGHCOMP, RELVERIFY, BOOLGADGET,
(APTR) &sel_brdr, NULL, &sav_text, 0, (APTR) NULL,
SAV_GAD, NULL },
add_gdgt = { NULL, 137,87,48,7, GADGHCOMP, RELVERIFY, BOOLGADGET,
(APTR) &sel_brdr, NULL, &add_text, 0, (APTR) NULL,
ADD_GAD, NULL },
del_gdgt = { NULL, 198,87,48,7, GADGHCOMP, RELVERIFY, BOOLGADGET,
(APTR) &sel_brdr, NULL, &del_text, 0, (APTR) NULL,
DEL_GAD, NULL },
prv_gdgt = { NULL, 259,87,24,7, GADGIMAGE | GADGHCOMP,
RELVERIFY, BOOLGADGET,
(APTR) &prv_img, NULL, NULL, 0, (APTR) NULL,
PRV_GAD, NULL },
nxt_gdgt = { NULL, 283,87,24,7, GADGIMAGE | GADGHCOMP,
RELVERIFY, BOOLGADGET,
(APTR) &nxt_img, NULL, NULL, 0, (APTR) NULL,
NXT_GAD, NULL },
neg_gdgt = { NULL, 222,3,24,8, GADGHNONE,
RAWKEY | TOGGLESELECT | ENDGADGET, BOOLGADGET | REQGADGET,
(APTR) &neg_brdr, NULL, &neg_text, 0, (APTR) NULL,
NEG_GAD, NULL },
pos_gdgt = { &neg_gdgt, 182,3,24,8, GADGHNONE,
RAWKEY | TOGGLESELECT | ENDGADGET, BOOLGADGET | REQGADGET,
(APTR) &neg_brdr, NULL, &pos_text, 0, (APTR) NULL,
POS_GAD, NULL };
struct Requester
vfy_rqst = { NULL, 11,83,299,14, 0,0, &pos_gdgt, NULL, NULL, 0, YLWP,
NULL, NULL, NULL, NULL, NULL };
struct NewWindow
NewWdw = { 160,11,320,100, BLKP,WHTP,
CLOSEWINDOW | GADGETUP | RAWKEY | MOUSEBUTTONS,
WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | SMART_REFRESH |
NOCAREREFRESH | RMBTRAP | ACTIVATE,
NULL, NULL, NULL, NULL, NULL, 0,0,0,0, WBENCHSCREEN };
/*----------------------------- Main program -----------------------------*/
_main()
{
init();
StartKey(&BookIndexFile);
next();
moveptr(&nxt_gdgt,0);
while (TRUE) {
Wait(MESSAGE);
while (msg = (struct IntuiMessage *) GetMsg(wdw->UserPort)) {
class = msg->Class;
code = msg->Code;
qual = msg->Qualifier;
iadr = msg->IAddress;
ReplyMsg(msg);
if (class == GADGETUP)
gid = ((struct Gadget *) iadr)->GadgetID;
else
gid = 0;
if (!IGNORE_MSG) {
if ((find_flag) && (gid != NAM_GAD))
kill_find();
if (ABORT_MSG) {
moveptr(&nxt_gdgt,0);
} else {
switch (class) {
case GADGETUP:
dispatch_gad();
break;
case RAWKEY:
dispatch_key();
break;
case CLOSEWINDOW:
quit(0);
break;
}
}
}
}
}
}
/*--------------------------- Function dispatch --------------------------*/
dispatch_gad()
{
switch (gid) {
case FND_GAD:
set_find();
break;
case ADD_GAD:
add();
break;
case SAV_GAD:
save();
break;
case DEL_GAD:
delete();
break;
case PRV_GAD:
prev();
break;
case NXT_GAD:
next();
break;
case NAM_GAD:
if (find_flag)
find();
else
moveptr(&adr_gdgt,1);
break;
case ADR_GAD:
moveptr(&cit_gdgt,1);
break;
case CIT_GAD:
moveptr(&sta_gdgt,1);
break;
case STA_GAD:
moveptr(&zip_gdgt,1);
break;
case ZIP_GAD:
moveptr(&phn_gdgt,1);
break;
case PHN_GAD:
moveptr(¬_gdgt,1);
break;
case NOT_GAD:
moveptr(&nxt_gdgt,0);
break;
}
}
dispatch_key()
{
switch (code) {
case FND_KEY:
set_find();
break;
case SAV_KEY:
moveptr(&sav_gdgt,0);
save();
break;
case ADD_KEY:
moveptr(&add_gdgt,0);
add();
break;
case DEL_KEY:
moveptr(&del_gdgt,0);
delete();
break;
case PRV_KEY:
moveptr(&prv_gdgt,0);
prev();
break;
case NXT_KEY:
moveptr(&nxt_gdgt,0);
next();
break;
case EDT_KEY:
moveptr(&nam_gdgt,1);
break;
}
}
/*--------------------------- Function handlers --------------------------*/
set_find()
{
if (UsedRecs(&BookDataFile)) {
chkrec();
setmem(&BookRec,sizeof(BookRec),'\0');
showrec();
find_flag = TRUE;
moveptr(&nam_gdgt,1);
}
}
find()
{
if (strlen(BookRec.Name)) {
genkey(BookRec.Name,BookKey,sizeof(BKEY));
SearchKey(&BookIndexFile,&BookRecNum,BookKey);
if (!BFILE_OK)
PrevKey(&BookIndexFile,&BookRecNum,BookKey);
readrec();
} else {
kill_find();
}
moveptr(&fnd_gdgt,0);
}
kill_find()
{
BookRec = SaveRec;
showrec();
find_flag = FALSE;
}
save()
{
BKEY tmpkey;
if (UsedRecs(&BookDataFile)) {
PutRec(&BookDataFile,BookRecNum,&BookRec);
genkey(SaveRec.Name,tmpkey,sizeof(BKEY));
genkey(BookRec.Name,BookKey,sizeof(BKEY));
if (strncmp(tmpkey,BookKey,sizeof(BKEY))) {
DeleteKey(&BookIndexFile,&BookRecNum,tmpkey);
AddKey(&BookIndexFile,BookRecNum,BookKey);
FindKey(&BookIndexFile,&BookRecNum,BookKey);
}
SaveRec = BookRec;
}
}
add()
{
if (strlen(BookRec.Name)) {
genkey(BookRec.Name,BookKey,sizeof(BKEY));
FindKey(&BookIndexFile,&BookRecNum,BookKey);
if (BFILE_OK)
BFILE_OK = !verify(&avf_text);
if (!BFILE_OK) {
AddRec(&BookDataFile,&BookRecNum,&BookRec);
genkey(BookRec.Name,BookKey,sizeof(BKEY));
AddKey(&BookIndexFile,BookRecNum,BookKey);
FindKey(&BookIndexFile,&BookRecNum,BookKey);
showusd();
}
SaveRec = BookRec;
}
}
delete()
{
if (UsedRecs(&BookDataFile)) {
if (verify(&dvf_text)) {
DeleteKey(&BookIndexFile,&BookRecNum,BookKey);
DeleteRec(&BookDataFile,BookRecNum);
SearchKey(&BookIndexFile,&BookRecNum,BookKey);
if (!BFILE_OK)
PrevKey(&BookIndexFile,&BookRecNum,BookKey);
showusd();
readrec();
}
}
}
next()
{
if (UsedRecs(&BookDataFile)) {
chkrec();
NextKey(&BookIndexFile,&BookRecNum,BookKey);
if (!BFILE_OK) {
DisplayBeep(NULL);
PrevKey(&BookIndexFile,&BookRecNum,BookKey);
}
readrec();
}
}
prev()
{
if (UsedRecs(&BookDataFile)) {
chkrec();
PrevKey(&BookIndexFile,&BookRecNum,BookKey);
if (!BFILE_OK) {
DisplayBeep(NULL);
NextKey(&BookIndexFile,&BookRecNum,BookKey);
}
readrec();
}
}
/*---------------------------- Initialization ----------------------------*/
init()
{
struct Gadget *p;
int x1,y1,x2,y2;
register int i;
if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",0)))
quit(-1);
if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0)))
quit(-2);
if (!(dev = CreatePort(0,0)))
quit(-3);
if (!(req = CreateStdIO(dev)))
quit(-4);
if (OpenDevice("input.device",0,req,0))
quit(-5);
req->io_Command = IND_WRITEEVENT;
req->io_Flags = 0;
req->io_Length = sizeof(struct InputEvent);
OpenFile(&BookDataFile,"BLKBOOK.DAT",sizeof(BookRec));
if (BFILE_OK)
OpenIndex(&BookIndexFile,"BLKBOOK.IDX",sizeof(BKEY),DUP);
if (!BFILE_OK) {
MakeFile(&BookDataFile,"BLKBOOK.DAT",sizeof(BookRec));
if (BFILE_OK)
MakeIndex(&BookIndexFile,"BLKBOOK.IDX",sizeof(BKEY),DUP);
}
if (!BFILE_OK)
quit(-6);
if (!(wdw = (struct Window *) OpenWindow(&NewWdw)))
quit(-7);
rp = wdw->RPort;
if (font = OpenFont(&attr))
SetFont(rp,font);
SetWindowTitles(wdw,wdwttl,scrttl);
SetAPen(rp,BLKP);
RectFill(rp,1,10,318,98);
DrawBorder(rp,&sel_brdr,258,87);
SetAPen(rp,BLUP);
for (i = 1, p = &nam_gdgt; i <= WDW_GAD; i++, p++) {
if (p->GadgetID <= STR_GAD) {
x1 = p->LeftEdge;
y1 = p->TopEdge;
x2 = x1 + p->Width - 1;
y2 = y1 + p->Height - 1;
RectFill(rp,x1,y1,x2,y2);
}
AddGadget(wdw,p,-1);
}
SetAPen(rp,WHTP);
RefreshGadgets(wdw->FirstGadget,wdw,NULL);
showusd();
}
/*---------------------------- Misc functions ----------------------------*/
readrec()
{
GetRec(&BookDataFile,BookRecNum,&BookRec);
showrec();
genkey(BookRec.Name,BookKey,sizeof(BKEY));
SaveRec = BookRec;
}
showrec()
{
struct StringInfo *p;
register int i;
for (i = 1, p = &nam_info; i <= STR_GAD; i++, p++)
pad(p->Buffer,p->MaxChars);
strncpy(Note,BookRec.Note,sizeof(Note));
PrintIText(rp,&nam_disp,0,0);
for (i = 1, p = &nam_info; i <= STR_GAD; i++, p++)
p->NumChars = trim(p->Buffer);
}
pad(str,len)
char *str;
int len;
{
setmem(&str[strlen(str)],len - strlen(str),' ');
str[len - 1] = '\0';
}
trim(str)
char *str;
{
register int i;
for (i = strlen(str) - 1; (i >= 0) && (str[i] == ' '); str[i--] = '\0');
return(++i);
}
showusd()
{
sprintf(used,"%5d",UsedRecs(&BookDataFile));
PrintIText(rp,&usd_text,270,15);
}
genkey(src,dst,len)
char *src;
char *dst;
int len;
{
while (len--)
(*src) ? (*dst++ = toupper(*src++)) : (*dst++ = ' ');
}
chkrec()
{
if (strcmp(BookRec.Name ,SaveRec.Name ) ||
strcmp(BookRec.Addr ,SaveRec.Addr ) ||
strcmp(BookRec.City ,SaveRec.City ) ||
strcmp(BookRec.State,SaveRec.State) ||
strcmp(BookRec.Zip ,SaveRec.Zip ) ||
strcmp(BookRec.Phone,SaveRec.Phone) ||
strcmp(BookRec.Note ,SaveRec.Note ))
if (verify(&svf_text))
save();
}
moveptr(gad,butn)
struct Gadget *gad;
int butn;
{
epos.ie_X = ebut.ie_X =
wdw->LeftEdge + gad->LeftEdge + gad->Width - 2;
epos.ie_Y = ebut.ie_Y =
(wdw->TopEdge + gad->TopEdge + gad->Height - 1) << 1;
if (butn)
req->io_Data = (APTR) &ebut;
else
req->io_Data = (APTR) &epos;
DoIO(req);
}
verify(txt)
struct IntuiText *txt;
{
vfy_rqst.ReqText = txt;
pos_gdgt.Flags &= ~SELECTED;
neg_gdgt.Flags &= ~SELECTED;
Request(&vfy_rqst,wdw);
Wait(MESSAGE);
msg = (struct IntuiMessage *) GetMsg(wdw->UserPort);
ReplyMsg(msg);
return((int) pos_gdgt.Flags & SELECTED);
}
/*----------------------------- Termination ------------------------------*/
quit(err)
int err;
{
CloseFile(&BookDataFile);
CloseIndex(&BookIndexFile);
if (req) {
CloseDevice(req);
DeleteStdIO(req);
}
if (dev)
DeletePort(dev);
if (font)
CloseFont(font);
if (wdw)
CloseWindow(wdw);
if (GfxBase)
CloseLibrary(GfxBase);
if (IntuitionBase)
CloseLibrary(IntuitionBase);
OpenWorkBench();
exit(err);
}